/**
 * Created by wangzhanming on 2018/2/7.
 */
(function ($) {
    //默认配置
    var defaultOption = {
        fields: [{                          //筛选条件字段。初始化筛选框时应提供该参数用于填充筛选字段下拉列表。
            fieldCode: "code_02",           //字段编码
            fieldName: "整数类型选项",        //字段名称
            fieldType: "INT",       //字段类型
        }, {
            fieldCode: "code_01",
            fieldName: "文本类型选项",
            fieldType: "TEXT",
        }, {
            fieldCode: "code_03",
            fieldName: "浮点数类型选项",
            fieldType: "DOUBLE",
        }, {
            fieldCode: "code_04",
            fieldName: "主数据1",
            fieldType: "RADIO",
        }, {
            fieldCode: "code_07",
            fieldName: "主数据2字段非常长字段非常长",
            fieldType: "RADIO",
        }, {
            fieldCode: "code_05",
            fieldName: "时间01",
            fieldType: "DATE",
        }, {
            fieldCode: "code_06",
            fieldName: "时间02",
            fieldType: "TIMESTAMP",
        }],
        showHead: true,                     //是否显示检索名称
        showSerial: true,                   //不启用高级公式时是否显示条件序号
        maxOptions: 0,                      //最多添加条件数量，0表示无限制
        editable: true,                     //筛选框是否可编辑（筛选条件仅做展示时可设置为false）
        onConditionChange: undefined,       //筛选条件改变时回调函数
        /**
         * 异步加载主数据函数。
         * ["RADIO", "RADIOTREE", "MULTISELECTTREE", "MULTISELECT", "DROPDOWNBOX", "USERIDRELATIONSHIP", "COMPANYIDRELATIONSHIP", "DEPARTIDRELATIONSHIP", "DROPDOWNBOXTEXT"]类型的字段可视为主数据，提供此函数后筛选条件的值由输入框变为下拉框。
         * 参数为筛选条件字段field，包含fieldCode、fieldName和fieldType三个字段。
         * 返回值应为一个数组，数组元素为json对象且包含valueCode和valueName两个字段。
         */
        onMasterData: undefined,
        data: {                             //复原筛选框时需要提供该参数。data是通过调用getFilterData方法获取到到json对象。
            version: '1.2.3',               //数据版本
            filterName: '',                 //检索名称
            /**
             * 检索条件数组。其中元素为json对象包含以下字段：
             * serialNumber     //序号
             * fieldCode        //字段编码
             * fieldName        //字段名称
             * fieldType        //字段类型
             * operator         //运算符编码
             * operatorName     //运算符名称
             * value            //值
             * isMasterData     //该字段是否是主数据类型
             * valueCode        //主数据编码
             * valueName        //主数据值
             */
            conditions: [],
            isAdvanced: false,              //是否启用高级公式
            expression: '',                 //高级公式
        },
    };

    //筛选框
    var filterBoxs = [];

    //有效配置
    var options = {};

    //下拉框
    var masterDataTypes = ["RADIO", "RADIOTREE", "MULTISELECTTREE", "MULTISELECT", "DROPDOWNBOX", "USERIDRELATIONSHIP", "COMPANYIDRELATIONSHIP", "DEPARTIDRELATIONSHIP", "DROPDOWNBOXTEXT"];
    //输入框
    var normalDataTypes = ["TEXT", "EMAIL", "IMAGE", "DOUBLE", "TEXTAREA", "CURRENCY", "INT", "TELPHONE", "CELLPHONE", "BANKACCOUNT", "ENCLOSURE", "ADDRESS", "ENGLISH", "CHINESE", "URL",
        "MULTITOONE", "IDRELATIONSHIP", "NAMERELATIONSHIP"];
    //时间控件
    var timeDataTypes = ["DATE", "TIMESTAMP"];

    //初始化并校验参数
    function validateOption(FB_index, filterBoxOption) {
        if (!filterBoxOption) {
            options[FB_index] = defaultOption;
        } else {
            options[FB_index] = {};
            for (var key in defaultOption) {
                if (defaultOption.hasOwnProperty(key)) {
                    if (typeof filterBoxOption[key] == 'undefined') {
                        options[FB_index][key] = defaultOption[key];
                    } else {
                        options[FB_index][key] = filterBoxOption[key];
                    }
                }
            }
        }

        //验证option.data.conditions是否合法
        var conditions = options[FB_index].data.conditions;
        if (options[FB_index].maxOptions && conditions && options[FB_index].maxOptions < conditions.length) {
            throw "maxOptions " + options[FB_index].maxOptions + " 小于data.conditions.length " + conditions.length;
        }
        if (conditions && conditions.length > 0) {
            var validateConditions = [];
            var length = conditions.length;
            for (var i = 0; i < length; i++) {
                var validate = false;
                for (var j = 0; j < conditions.length; j++) {
                    var condition = conditions[j];
                    if (Number(condition.serialNumber) == i + 1) {
                        validateConditions.push(conditions.splice(j, 1)[0]);
                        validate = true;
                        break;
                    }
                }
                if (!validate) {
                    throw "请检查 option.data.conditions";
                }
            }
            options[FB_index].data.conditions = validateConditions;
        }
    }

    //添加验证
    function addValidate(FB_index) {

        var option = {
            message: 'This value is not valid',
            feedbackIcons: {
                valid: 'glyphicon glyphicon-ok',
                invalid: 'glyphicon glyphicon-remove',
                validating: 'glyphicon glyphicon-refresh'
            },
            fields: {}
        };
        option.fields["FB_conditionValue_legal"] = {
            validators: {
                callback: {
                    message: '',
                    callback: function (value, validator, field) {
                        return true;
                    }
                }
            }
        };
        option.fields["FB_" + FB_index + "_filterName"] = {
            validators: {
                regexp: {
                    regexp: /^([a-z|A-Z|\u4e00-\u9fa5|0-9])*$/,
                    message: '检索名称只能由字母,数字，汉字组成'
                },
                notEmpty: {
                    message: '检索名称不能为空'
                },
                stringLength: {
                    max: 32,
                    message: '检索名称不能超过32个字符'
                }
            }
        };
        option.fields["FB_" + FB_index + "_conditionValue"] = {
            validators: {
                callback: {
                    message: 'The password is not valid',
                    callback: function (value, validator, field) {
                        var conditionItemDiv = field.parent();
                        var conditionField = conditionItemDiv.children("div.FB_conditionField").children("[name='FB_" + FB_index + "_conditionField']");
                        var conditionOperator = conditionItemDiv.children("div.FB_conditionOperator").children("[name='FB_" + FB_index + "_conditionOperator']");
                        var fieldType = conditionField.children(":selected").data("type");
                        var operator = conditionOperator.children(":selected").val();

                        if (-1 != ["DATE", "TIMESTAMP"].indexOf(fieldType)) {
                            return true;
                        }

                        if (-1 != ['NULL', 'NOT_NULL'].indexOf(operator)) {
                            return true;
                        } else if ("INT" == fieldType) {
                            return {
                                message: '必须输入一个整数',
                                valid: /^(?:-?(?:0|[1-9][0-9]*))$/.test(value),
                            }
                        } else if ("DOUBLE" == fieldType || "CURRENCY" == fieldType) {
                            return {
                                message: '必须输入一个数字',
                                valid: !isNaN(parseFloat(value)) && isFinite(value),
                            }
                        } else {
                            return {
                                message: '至少输入一个字符',
                                valid: /^.+$/.test(value),
                            }
                        }
                    }
                }
            }
        };
        option.fields["FB_" + FB_index + "_expression"] = {
            validators: {
                callback: {
                    message: '请看提示',
                    callback: function (value, validator, field) {
                        var nums = ["p"];
                        var words = [];

                        function validate1(words) {
                            if (!words) {
                                return false;
                            }
                            if (words.length == 1) {
                                if (-1 != nums.indexOf(words[0])) {
                                    return true;
                                }
                            } else {
                                var wordStr = words.join("");
                                words = wordStr.split("and");
                                if (words.length <= 1) {
                                    words = wordStr.split("or");
                                }
                                for (var i = 0; i < words.length; i++) {
                                    if (-1 == nums.indexOf(words[i])) {
                                        return false;
                                    }
                                }
                                return true;
                            }
                            return false;
                        }

                        function validate2() {
                            if (!words || words.length == 0) {
                                return false;
                            }
                            if (words[0] != "(") {
                                words.splice(0, 0, "(");
                                words.push(")");
                            }

                            var length = words.length;
                            var lefts = [];
                            var right;

                            for (var i = 0; i < length; i++) {
                                var world = words[i];
                                if ("(" == world) {
                                    lefts.push(i);
                                }
                                if (")" == world) {
                                    right = i;
                                    if (lefts.length == 0) {
                                        return false;
                                    }
                                    var left = lefts.pop();
                                    var subWord = words.splice(left, right - left + 1, "p");

                                    subWord.shift();
                                    subWord.pop();

                                    if (!validate1(subWord)) {
                                        return false;
                                    }

                                    i = left;
                                    length = words.length;
                                }
                            }
                            return validate1(words);
                        }

                        var conditionNums = $("#FB_" + FB_index + "_filterConditions").children("div[name='FB_" + FB_index + "_conditionItemDiv']").length;
                        if (conditionNums == 0) {
                            return !value || value == '';
                        } else {
                            for (var i = 1; i <= conditionNums; i++) {
                                nums.push("" + i);
                            }
                            value = value.replace(/ /g, "");
                            for (; value.length > 0;) {
                                if (value.startsWith("(")) {
                                    words.push("(");
                                    value = value.substr(1);
                                } else if (value.startsWith(")")) {
                                    words.push(")");
                                    value = value.substr(1);
                                } else if (value.startsWith("and")) {
                                    words.push("and");
                                    value = value.substr(3);
                                } else if (value.startsWith("or")) {
                                    words.push("or");
                                    value = value.substr(2);
                                } else {
                                    var isNum = false;
                                    for (var i = nums.length - 1; i >= 0; i--) {
                                        if (value.startsWith(nums[i])) {
                                            words.push(nums[i]);
                                            value = value.substr(nums[i].length);
                                            isNum = true;
                                            break;
                                        }
                                    }
                                    if (!isNum) {
                                        return false;
                                    }
                                }
                            }
                        }
                        return validate2();
                    },
                }
            }
        };

        $("div[FB_index=" + FB_index + "]").bootstrapValidator(option);
    }

    //回调函数
    function conditionChange(FB_index) {
        var option = options[FB_index];
        if (option.onConditionChange && option.editable) {
            var conditions = $("div[FB_index=" + FB_index + "]").getFilterData();
            if (conditions) {
                option.onConditionChange(conditions);
            }
        }
    }

    //设置序号
    function setSerialNumber(FB_index) {
        var conditionItemDivs = $("#FB_" + FB_index + "_filterConditions").children("div[name='FB_" + FB_index + "_conditionItemDiv']");
        for (var i = 0; i < conditionItemDivs.length; i++) {
            var conditionItemDiv = conditionItemDivs[i];
            $(conditionItemDiv).children("span[name='FB_" + FB_index + "_conditionSerialNumber']").text(i + 1);
        }

        if (!$("#FB_" + FB_index + "_isAdvanced").is(":checked") && !options[FB_index].showSerial) {
            conditionItemDivs.children("span[name='FB_" + FB_index + "_conditionSerialNumber']").hide();
        } else {
            conditionItemDivs.children("span[name='FB_" + FB_index + "_conditionSerialNumber']").show();
        }
    }

    function setOperator(conditionOperator, type) {
        conditionOperator.empty();
        switch (type) {
            case "TEXT":
            case "EMAIL":
            case "TEXTAREA":
                conditionOperator.append($("<option value='EQUAL'></option>").text("等于"));
                conditionOperator.append($("<option value='NOT_EQUAL'></option>").text("不等于"));
                conditionOperator.append($("<option value='NULL'></option>").text("为空"));
                conditionOperator.append($("<option value='NOT_NULL'></option>").text("不为空"));
                conditionOperator.append($("<option value='CONTAIN'></option>").text("包含"));
                break;
            case "IMAGE":
            case "TELPHONE":
            case "CELLPHONE":
            case "BANKACCOUNT":
            case "ENCLOSURE":
            case "ADDRESS":
            case "ENGLISH":
            case "CHINESE":
            case "URL":
                conditionOperator.append($("<option value='EQUAL'></option>").text("等于"));
                conditionOperator.append($("<option value='NOT_EQUAL'></option>").text("不等于"));
                conditionOperator.append($("<option value='NULL'></option>").text("为空"));
                conditionOperator.append($("<option value='NOT_NULL'></option>").text("不为空"));
                break;
            case "DOUBLE":
            case "CURRENCY":
            case "INT":
                conditionOperator.append($("<option value='EQUAL'></option>").text("等于"));
                conditionOperator.append($("<option value='NOT_EQUAL'></option>").text("不等于"));
                conditionOperator.append($("<option value='NULL'></option>").text("为空"));
                conditionOperator.append($("<option value='NOT_NULL'></option>").text("不为空"));
                conditionOperator.append($("<option value='GT'></option>").text("大于"));
                conditionOperator.append($("<option value='LT'></option>").text("小于"));
                conditionOperator.append($("<option value='GE'></option>").text("大于等于"));
                conditionOperator.append($("<option value='LE'></option>").text("小于等于"));
                break;
            case "DATE":
            case "TIMESTAMP":
                conditionOperator.append($("<option value='RANGE'></option>").text("时间范围"));
                conditionOperator.append($("<option value='GT'></option>").text("大于"));
                conditionOperator.append($("<option value='LT'></option>").text("小于"));
                conditionOperator.append($("<option value='GE'></option>").text("大于等于"));
                conditionOperator.append($("<option value='LE'></option>").text("小于等于"));
                conditionOperator.append($("<option value='TODAY'></option>").text("今天"));
                conditionOperator.append($("<option value='YESTERDAY'></option>").text("昨天"));
                conditionOperator.append($("<option value='WEEK'></option>").text("本周"));
                conditionOperator.append($("<option value='MONTH'></option>").text("本月"));
                break;
            case "RADIO":
            case "RADIOTREE":
            case "MULTISELECTTREE":
            case "MULTISELECT":
            case "DROPDOWNBOX":
            case "USERIDRELATIONSHIP":
            case "COMPANYIDRELATIONSHIP":
            case "DEPARTIDRELATIONSHIP":
            case "DROPDOWNBOXTEXT":
                conditionOperator.append($("<option value='EQUAL'></option>").text("等于"));
                conditionOperator.append($("<option value='NOT_EQUAL'></option>").text("不等于"));
                conditionOperator.append($("<option value='NULL'></option>").text("为空"));
                break;
            case "MULTITOONE":
            case "IDRELATIONSHIP":
            case "NAMERELATIONSHIP":
                conditionOperator.append($("<option value='EQUAL'></option>").text("等于"));
                break;
            default:
                conditionOperator.append($("<option value='EQUAL'></option>").text("等于"));
                break;
        }
        conditionOperator.selectpicker('refresh');
    }

    //删除条件
    function removeCondition(FB_index, e) {
        e.stopPropagation();
        var conditionItemDiv = $(e.target).parent();
        var conditionValue = conditionItemDiv.children("[name='FB_" + FB_index + "_conditionValue']");
        if (conditionValue.length == 1) {
            if ("INPUT" == conditionValue.prop("tagName")) {
                $("div[FB_index=" + FB_index + "]").bootstrapValidator('removeField', conditionValue);
            }
        } else {
            conditionValue = conditionItemDiv.children("div.bootstrap-select").children("[name='FB_" + FB_index + "_conditionValue']");
            conditionValue.selectpicker('destroy');
        }
        conditionItemDiv.remove();

        //删除条件后须重新设置序号
        setSerialNumber(FB_index);

        //删除条件后须重新验证公式
        if ($("#FB_" + FB_index + "_isAdvanced").is(":checked")) {
            $("div[FB_index=" + FB_index + "]").bootstrapValidator('revalidateField', $("#FB_" + FB_index + "_expression"));
        }
        conditionChange(FB_index);
    }

    function addCondition(FB_index, condition) {
        var option = options[FB_index];
        var filterBox = $("div[FB_index=" + FB_index + "]");
        if (option.maxOptions && option.maxOptions <= $("#FB_" + FB_index + "_filterConditions").children("div[name='FB_" + FB_index + "_conditionItemDiv']").length) {
            alert("不能创建更多条件");
            return;
        }

        //每个条件用div 标签包裹
        var conditionItemDiv = $("<div name='FB_" + FB_index + "_conditionItemDiv' class='form-group FB_view-display'></div>");
        $("#FB_" + FB_index + "_filterConditions").append(conditionItemDiv);

        //序号
        conditionItemDiv.append($("<span name='FB_" + FB_index + "_conditionSerialNumber'></span>"));
        conditionItemDiv.append($("<span>&nbsp</span>"));

        //字段
        var conditionField = $("<select name='FB_" + FB_index + "_conditionField' class='selectpicker FB_conditionField' data-live-search='true'></select>")
        if (condition && !option.editable) {
            conditionField.append($("<option value='" + condition.fieldCode + "' data-type='" + condition.fieldType + "'></option>").text(condition.fieldName));
        } else {
            for (var i = 0; i < option.fields.length; i++) {
                var field = option.fields[i];
                conditionField.append($("<option value='" + field.fieldCode + "' data-type='" + field.fieldType + "'></option>").text(field.fieldName));
            }
        }
        conditionItemDiv.append(conditionField);
        conditionItemDiv.append($("<span>&nbsp</span>"));
        //赋值
        condition && conditionField.val(condition.fieldCode);
        conditionField.selectpicker('refresh');


        //运算符
        var conditionOperator = $("<select name='FB_" + FB_index + "_conditionOperator' class='selectpicker FB_conditionOperator'></select>")
        conditionItemDiv.append(conditionOperator);
        setOperator(conditionOperator, conditionField.children(":selected").data("type"));
        conditionItemDiv.append($("<span>&nbsp</span>"));
        //赋值
        condition && conditionOperator.val(condition.operator);
        conditionOperator.selectpicker('refresh');


        //值
        var conditionValue = $("<input type='text' name='FB_" + FB_index + "_conditionValue' class='FB_form-control FB_input FB_margin' conditionValueType='normal'>");
        conditionItemDiv.append(conditionValue);
        if (option.editable) {
            filterBox.bootstrapValidator('addField', conditionValue);
        }
        conditionValue = updateOperatorValue(FB_index, conditionItemDiv, condition);


        //删除按钮
        if (option.editable) {
            var remover = $("<a href='javascript:void(0)' name='FB_" + FB_index + "_conditionRemover' class='FB_conditionRemover'>删除</a>");
            conditionItemDiv.append(remover);
        }

        //每次添加条件需要更新序号
        setSerialNumber(FB_index);

        //添加条件后需要调用回调函数
        if (!$("#FB_" + FB_index + "_isAdvanced").is(":checked")) {
            conditionChange(FB_index);
        }

        if (option.editable) {
            //添加条件后须重新验证公式
            if ($("#FB_" + FB_index + "_isAdvanced").is(":checked")) {
                $("div[FB_index=" + FB_index + "]").bootstrapValidator('revalidateField', $("#FB_" + FB_index + "_expression"));
            }

            remover.on("click", function (e) {
                removeCondition(FB_index, e);
            });

            conditionField.on("change", function () {
                //条件字段改变需要更新操作符
                var type = $(this).children(":selected").data("type");
                setOperator(conditionOperator, type);

                //条件字段改变需要重新验证条件值
                conditionValue = updateOperatorValue(FB_index, conditionItemDiv);
                //条件改变
                conditionChange(FB_index);
            });
            conditionOperator.on("change", function () {
                //条件字段改变需要重新验证条件值
                var conditionValueType = conditionValue.attr("conditionValueType");
                if ("normal" == conditionValueType) {
                    filterBox.bootstrapValidator('revalidateField', conditionValue);
                }
                if ("time" == conditionValueType) {
                    var range = conditionValue.attr("range");
                    var operator = conditionOperator.val();
                    //范围转时间点
                    if ("true" == range && -1 != ["GT", "LT", "GE", "LE"].indexOf(operator)) {
                        conditionValue.remove();
                        conditionValue = createTimeConditionValue(FB_index, conditionOperator, false);
                    } else if ("false" == range && -1 == ["GT", "LT", "GE", "LE"].indexOf(operator)) {
                        //时间点转范围
                        conditionValue.remove();
                        conditionValue = createTimeConditionValue(FB_index, conditionOperator, true);
                    }
                    if (-1 == ["GT", "LT", "GE", "LE"].indexOf(operator)) {
                        setTimeConditionValue(conditionValue, operator);
                    }
                }
                conditionChange(FB_index);
            });
            conditionValue.on("change", function () {
                conditionChange(FB_index);
            });
        }
        return conditionItemDiv;
    }

    function createTimeConditionValue(FB_index, conditionOperator, range) {
        var conditionValueId = "FB_" + new Date().getTime();
        var conditionValueClass = range ? "FB_input_lg" : "FB_input";
        var conditionValue = $("<input type='text' id='" + conditionValueId + "' name='FB_" + FB_index + "_conditionValue' class='FB_form-control " + conditionValueClass + " FB_margin' conditionValueType='time' range='" + range + "'>");
        conditionOperator.parent().next("span").after(conditionValue);
        laydate.render({
            elem: "#" + conditionValueId,
            type: 'datetime',
            range: range,
            format: 'yyyy-MM-dd HH:mm:ss'
        });
        return conditionValue;
    }


    function dateToStr(date) {
        function pad(number) {
            if (number < 10) {
                return '0' + number;
            }
            return number;
        }

        return date.getFullYear() +
            '-' + pad(date.getMonth() + 1) +
            '-' + pad(date.getDate()) +
            ' ' + pad(date.getHours()) +
            ':' + pad(date.getMinutes()) +
            ':' + pad(date.getSeconds());
    }

    function setTimeConditionValue(conditionValue, operator) {
        var startDate = new Date();
        var endDate = new Date();
        switch (operator) {
            case "RANGE":
            case "TODAY":
                startDate.setHours(0);
                startDate.setMinutes(0);
                startDate.setSeconds(0);
                break;
            case "YESTERDAY":
                startDate.setDate(startDate.getDate() - 1);
                startDate.setHours(0);
                startDate.setMinutes(0);
                startDate.setSeconds(0);
                endDate.setHours(0);
                endDate.setMinutes(0);
                endDate.setSeconds(0);
                break;
            case "WEEK":
                startDate.setDate(startDate.getDate() - startDate.getDay());
                startDate.setHours(0);
                startDate.setMinutes(0);
                startDate.setSeconds(0);
                break;
            case "MONTH":
                startDate.setMonth(startDate.getMonth() - 1);
                startDate.setDate(1);
                startDate.setHours(0);
                startDate.setMinutes(0);
                startDate.setSeconds(0);
                break;
        }
        var startDateStr = dateToStr(startDate);
        var endDateStr = dateToStr(endDate);
        conditionValue.val(startDateStr + " - " + endDateStr);
    }

    //更新conditionValue
    function updateOperatorValue(FB_index, conditionItemDiv, condition) {
        var option = options[FB_index];
        var filterBox = $("div[FB_index=" + FB_index + "]");
        var conditionField = conditionItemDiv.children("div.FB_conditionField").children("[name='FB_" + FB_index + "_conditionField']");
        var conditionOperator = conditionItemDiv.children("div.FB_conditionOperator").children("[name='FB_" + FB_index + "_conditionOperator']");
        var conditionValue = conditionItemDiv.children("[name='FB_" + FB_index + "_conditionValue']");
        conditionValue = conditionValue.length == 1 ? conditionValue : conditionItemDiv.children("div.bootstrap-select").children("[name='FB_" + FB_index + "_conditionValue']");
        var tagName = conditionValue.prop("tagName");
        var fieldCode = conditionField.children(":selected").val();
        var fieldType = conditionField.children(":selected").data("type");
        var conditionValueType = conditionValue.attr("conditionValueType");

        var mayBeMasterData = option.onMasterData || (condition && condition.isMasterData);
        var masterDataButNormal = -1 != masterDataTypes.indexOf(fieldType) && !mayBeMasterData;

        //清除
        if ("normal" == conditionValueType && (-1 != timeDataTypes.indexOf(fieldType) || (-1 != masterDataTypes.indexOf(fieldType) && !masterDataButNormal))) {
            conditionValue.attr("name", "FB_conditionValue_legal");
            conditionValue.hide();
            if (option.editable) {
                filterBox.bootstrapValidator('addField', conditionValue);
            }
        } else if ("time" == conditionValueType && -1 == timeDataTypes.indexOf(fieldType)) {
            conditionValue.remove();
        } else if ("master" == conditionValueType && (-1 == masterDataTypes.indexOf(fieldType) || masterDataButNormal)) {
            conditionValue.selectpicker('destroy');
            conditionValue.remove();
        }

        //设置
        if (-1 != normalDataTypes.indexOf(fieldType) || masterDataButNormal) {
            if ("normal" != conditionValueType) {
                conditionValue = conditionItemDiv.children("input[conditionValueType='normal']");
                conditionValue.attr("name", "FB_" + FB_index + "_conditionValue");
                conditionValue.show();
            }
            if (condition) {
                conditionValue.val(condition.value);
            }
            if (option.editable) {
                filterBox.bootstrapValidator('revalidateField', conditionValue);
            }
        } else if (-1 != timeDataTypes.indexOf(fieldType) && "time" != conditionValueType) {
            var range = true;
            var operator = "RANGE";
            var value;
            if (condition) {
                operator = condition.operator;
                range = -1 == ["GT", "LT", "GE", "LE"].indexOf(operator);
                if (-1 != ["RANGE", "GT", "LT", "GE", "LE"].indexOf(operator)) {
                    value = condition.value;
                }
            }
            conditionValue = createTimeConditionValue(FB_index, conditionOperator, range);
            if (range) {
                setTimeConditionValue(conditionValue, operator);
            }
            if (value) {
                conditionValue.val(value);
            }
            conditionValue.on("change", function () {
                conditionChange(FB_index);
            });
        } else if (-1 != masterDataTypes.indexOf(fieldType) && !masterDataButNormal) {
            if ("master" != conditionValueType) {
                conditionValue = $("<select name='FB_" + FB_index + "_conditionValue' class='selectpicker FB_input FB_margin' data-live-search='true' conditionValueType='master'></select>");
                conditionOperator.parent().next("span").after(conditionValue);
                conditionValue.on("change", function () {
                    conditionChange(FB_index);
                });
            }
            if (fieldCode != conditionValue.attr("fieldCode")) {
                //需要修改选项
                conditionValue.empty();
                conditionValue.attr("fieldCode", fieldCode);
                if (!option.onMasterData && condition && condition.isMasterData) {
                    conditionValue.append($("<option value='" + condition.valueCode + "'></option>").text(condition.valueName));
                } else {
                    var masterData;
                    for (var i = 0; i < option.fields.length; i++) {
                        var field = option.fields[i];
                        if (fieldCode == field.fieldCode) {
                            masterData = field.masterData;
                            if (!masterData) {
                                masterData = option.onMasterData(field);
                                field.masterData = masterData;
                            }
                            break;
                        }
                    }
                    var masterDataLength = masterData ? masterData.length : 0;
                    for (var i = 0; i < masterDataLength; i++) {
                        conditionValue.append($("<option value='" + masterData[i].code + "'></option>").text(masterData[i].name));
                    }
                }
                conditionValue.selectpicker('refresh');
            }
            if (condition) {
                conditionValue.val(condition.value);
                conditionValue.selectpicker('refresh');
            }
        }
        return conditionValue;
    }

    function getDevaultExpression(FB_index) {
        var conditionItemDivs = $("#FB_" + FB_index + "_filterConditions").children("div[name='FB_" + FB_index + "_conditionItemDiv']");
        if (conditionItemDivs.length > 0) {
            var expression = "";
            for (var i = 1; i < conditionItemDivs.length; i++) {
                expression += i + " ";
                expression += "and ";
            }
            expression += i;
            return expression;
        }
        return '';
    }

    $.fn.initFilterBox = function (filterBoxOption) {
        if (this.hasInitFilterBox()) {
            throw "重新初始化前请先销毁";
        }

        this.addClass("FB_div");
        var FB_index = this.attr("FB_index");
        if (filterBoxs.indexOf(FB_index) == -1) {
            FB_index = "FB" + filterBoxs.length;
            this.attr("FB_index", FB_index);
            filterBoxs.push(FB_index);
        }

        //校验参数
        validateOption(FB_index, filterBoxOption);

        var option = options[FB_index];

        //添加验证
        if (option.editable) {
            addValidate(FB_index);
        }

        //初始化 headDiv
        if (option.showHead) {
            var headDiv = $("<div class='FB_container'></div>");
            headDiv.append($("<h5>检索名称</h5>"));
            headDiv.append($("<div class='form-group'><input type='text' class='FB_form-control FB_margin FB_input_lg' id='FB_" + FB_index + "_filterName' name='FB_" + FB_index + "_filterName' placeholder='自定义检索'></div>"));
            this.append(headDiv);

            if (option.data.filterName) {
                $("#FB_" + FB_index + "_filterName").val(option.data.filterName);
            }

            if (option.editable) {
                this.bootstrapValidator('addField', $("#FB_" + FB_index + "_filterName"));
            } else {
                $("#FB_" + FB_index + "_filterName").attr("disabled", "disabled");
            }
        }

        //初始化 conditionDiv
        var conditionDiv = $("<div class='FB_container'></div>");
        conditionDiv.append($("<h5>检索条件，支持复合查询</h5>"));
        conditionDiv.append($("<div id='FB_" + FB_index + "_filterConditions'></div>"));
        this.append(conditionDiv);

        if (option.editable) {
            conditionDiv.append($("<a href='javascript:void(0)' id='FB_" + FB_index + "_addCondition'><span class='glyphicon glyphicon-plus'>添加更多条件</span></a>"));
            $("#FB_" + FB_index + "_addCondition").on("click", function () {
                addCondition(FB_index);
            });
        }

        var conditions = option.data.conditions;
        if (conditions && conditions.length > 0) {
            for (var i = 0; i < conditions.length; i++) {
                var condition = conditions[i];
                var conditionItemDiv = addCondition(FB_index, condition);
                if (!option.editable) {
                    var conditionField = conditionItemDiv.children("div.FB_conditionField").children("[name='FB_" + FB_index + "_conditionField']");
                    conditionField.attr("disabled", "disabled");
                    conditionField.selectpicker('refresh');

                    var conditionOperator = conditionItemDiv.children("div.FB_conditionOperator").children("select[name='FB_" + FB_index + "_conditionOperator']");
                    conditionOperator.attr("disabled", "disabled");
                    conditionOperator.selectpicker('refresh');

                    var conditionValue = conditionItemDiv.children("[name='FB_" + FB_index + "_conditionValue']");
                    if (conditionValue.length == 1) {
                        conditionValue.attr("disabled", "disabled");
                    } else {
                        conditionValue = conditionItemDiv.children("div.bootstrap-select").children("[name='FB_" + FB_index + "_conditionValue']");
                        conditionValue.attr("disabled", "disabled");
                        conditionValue.selectpicker('refresh');
                    }
                }
            }
        }

        //初始化 advanceDiv
        var expressionDiv = $("<div id='FB_" + FB_index + "_expressionDiv' class='form-group'></div>");
        expressionDiv.append($("<input type='text' id='FB_" + FB_index + "_expression' name='FB_" + FB_index + "_expression' class='FB_form-control FB_input_lg'>"));

        if (option.editable) {
            expressionDiv.append($("<span>&nbsp</span>"));
            expressionDiv.append($("<span class='glyphicon glyphicon-question-sign FB_margin' id='FB_" + FB_index + "_question'></span>"));
        }
        var advanceDiv = $("<div class='FB_container'></div>");
        advanceDiv.append($("<div class='check-box'><label><input type='checkbox' id='FB_" + FB_index + "_isAdvanced'><span>启用高级公式</span></label></div>"));
        advanceDiv.append(expressionDiv);
        this.append(advanceDiv);

        //初始化提示框
        if (option.editable) {
            $("#FB_" + FB_index + "_question").popover({
                container: 'body',
                html: true,
                placement: 'right',
                trigger: 'hover',
                title: '<h6>请按照如下规则编辑条件组合</h6>' +
                '<p class="text-left text-success">(1 and 2) or (3 and 4)  <span class="glyphicon glyphicon-ok"></span></p>' +
                '<p class="text-left text-info">1、有and和or，必须要有括号</p>' +
                '<p class="text-left text-danger">1 and 2 or 3 and 4  <span class="glyphicon glyphicon-remove"></span></p>' +
                '<p class="text-left text-info">2、一个括号不能同时出现and和or</p>' +
                '<p class="text-left text-danger">(1 and 2 or 3) and 4  <span class="glyphicon glyphicon-remove"></span></p>' +
                '<p class="text-left text-info">3、不允许出现不存在的编号</p>' +
                '<p class="text-left text-danger">1 and 2 and 3 and 4 and 5  <span class="glyphicon glyphicon-remove"></span></p>' +
                '<p class="text-left text-info">4、括号都是成对出现</p>' +
                '<p class="text-left text-danger">(1 and 2 or 3 and 4  <span class="glyphicon glyphicon-remove"></span></p>',
            });

            //添加公式验证
            this.bootstrapValidator('addField', $("#FB_" + FB_index + "_expression"));

            //默认不勾选高级公式
            $("#FB_" + FB_index + "_expressionDiv").hide();

            $("#FB_" + FB_index + "_isAdvanced").change(function () {
                if ($("#FB_" + FB_index + "_isAdvanced").is(":checked")) {
                    $("#FB_" + FB_index + "_expressionDiv").show();
                    //设置高级表达式
                    $("#FB_" + FB_index + "_expression").val(getDevaultExpression(FB_index));
                } else {
                    $("#FB_" + FB_index + "_expressionDiv").hide();
                }
                setSerialNumber(FB_index);
            });
        }

        if (option.data.isAdvanced) {
            $("#FB_" + FB_index + "_isAdvanced").click();
        }
        if (option.data.expression) {
            $("#FB_" + FB_index + "_expression").val(option.data.expression);
        }

        if (option.editable) {
            $("#FB_" + FB_index + "_expression").on("change", function () {
                conditionChange(FB_index);
            });
        } else {
            $("#FB_" + FB_index + "_isAdvanced").attr("disabled", "disabled");
            $("#FB_" + FB_index + "_expression").attr("disabled", "disabled");
        }
    }

    $.fn.hasInitFilterBox = function () {
        var FB_index = this.attr("FB_index");
        if (FB_index && -1 != filterBoxs.indexOf(FB_index)) {
            return true;
        }
        return false;
    }

    $.fn.destoryFilterBox = function () {
        var FB_index = this.attr("FB_index");
        var editable = false;
        if (FB_index) {
            editable = options[FB_index].editable;
            options[FB_index] = {};
            filterBoxs.splice(filterBoxs.indexOf(FB_index), 1);
        }
        this.removeAttr("FB_index");
        if (editable) {
            this.bootstrapValidator('destroy');
        }
        this.empty();
    }

    $.fn.getFilterData = function () {
        var FB_index = this.attr("FB_index");
        var option = options[FB_index];

        //获取数据前参数验证必须通过
        if (option.editable) {
            var bootstrapValidator = this.data('bootstrapValidator');
            bootstrapValidator.validate();
            if (!bootstrapValidator.isValid()) {
                return undefined;
            }
        }

        var data = {
            version: option.data.version,
        };
        if (option.showHead) {
            data.filterName = $("#FB_" + FB_index + "_filterName").val();
        }
        data.conditions = [];
        var conditionItemDivs = $("#FB_" + FB_index + "_filterConditions").children("div[name='FB_" + FB_index + "_conditionItemDiv']");
        for (var i = 0; i < conditionItemDivs.length; i++) {
            var conditionItemDiv = conditionItemDivs[i];
            var serialNumber = $(conditionItemDiv).children("span[name='FB_" + FB_index + "_conditionSerialNumber']").text();
            var conditionField = $(conditionItemDiv).children("div.FB_conditionField").children("[name='FB_" + FB_index + "_conditionField']");
            var fieldCode = conditionField.children(":selected").val();
            var fieldName = conditionField.children(":selected").text();
            var fieldType = conditionField.children(":selected").data("type");
            var conditionOperator = $(conditionItemDiv).children("div.FB_conditionOperator").children("select[name='FB_" + FB_index + "_conditionOperator']").children(":selected");
            var operator = conditionOperator.val();
            var operatorName = conditionOperator.text();
            var conditionValue = $(conditionItemDiv).children("[name='FB_" + FB_index + "_conditionValue']");
            conditionValue = conditionValue.length == 1 ? conditionValue : $(conditionItemDiv).children("div.bootstrap-select").children("[name='FB_" + FB_index + "_conditionValue']");
            var value = conditionValue.val();
            var conditionItem = {
                serialNumber: serialNumber,
                fieldCode: fieldCode,
                fieldName: fieldName,
                fieldType: fieldType,
                operator: operator,
                operatorName: operatorName,
                value: value,
                isMasterData: false,
            };
            if ("SELECT" == conditionValue.prop("tagName")) {
                conditionItem.isMasterData = true;
                conditionItem.valueCode = value;
                conditionItem.valueName = conditionValue.children(":selected").text();
            }
            data.conditions.push(conditionItem);
        }
        data.isAdvanced = $("#FB_" + FB_index + "_isAdvanced").is(":checked");
        data.expression = data.isAdvanced ? $("#FB_" + FB_index + "_expression").val() : getDevaultExpression(FB_index);
        return data;
    }
}(jQuery))